package flyshoes.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.net.URLEncodeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONString;
import cn.hutool.json.JSONUtil;
import flyshoes.mybatis.entity.Result;
import flyshoes.mybatis.entity.UserBaseInfo;
import flyshoes.mybatis.entity.UserDetailInfo;
import flyshoes.mybatis.entity.WeChatUser;
import flyshoes.mybatis.service.serviceImpl.UserbaseinfoServiceImpl;

import flyshoes.service.serviceImpl.WeChatLoginServiceImpl;
import flyshoes.utils.JwtUtil;
import org.apache.ibatis.io.Resources;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/user")
@ConditionalOnClass(DispatcherServlet.class)
public class WeChatLoginController {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WeChatLoginServiceImpl service;
    @Autowired
    private UserbaseinfoServiceImpl baseinfoService;


    @GetMapping("/getwechatcode")
    public Result<Map<String, Object>> getwechatcode() throws IOException {
        String weChatState = IdUtil.randomUUID();
        String myUrl = URLEncodeUtil.encode("http://22f8a8d6.r25.cpolar.top/user/wechatlogin");//微信授权后 回调我们服务起的链接 获得用户信息 这个需要公网ip,我们用的内网穿透
        //state传 statekey，得到用户信息后更新redis
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=wx8c4b07d38406f41f&redirect_uri=" + myUrl + "&response_type=code&scope=snsapi_userinfo&state=" + weChatState + "#wechat_redirect";
        ByteArrayOutputStream outArr = new ByteArrayOutputStream();
        QrConfig cfg = QrConfig.create();
        cfg.setHeight(300);
        cfg.setWidth(300);
        //System.out.println("现在图片是：" + Resources.getResourceAsFile("weixin.png"));
        cfg.setImg(Resources.getResourceAsFile("weixin.png"));
        QrCodeUtil.generate(url, cfg, "png", outArr);
        Map<String, Object> retData = new HashMap<>();
        redisTemplate.opsForValue().set("weChatState:"+weChatState, "100", 1, TimeUnit.HOURS);//100表示开始登陆  200 成功   300 失败登陆成功更新
        retData.put("state", weChatState);
        retData.put("img", Base64.encode(outArr.toByteArray()));
        return Result.success(retData);
    }

    @GetMapping("/wechatlogin") //这个是在手机上访问的
    public void wechatlogin(String code, String state, HttpServletResponse resp) throws IOException {
        //state 就是 statekey
        System.out.println("state1:------------------"+state);
        System.out.println("code:" + code);
        String getUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx8c4b07d38406f41f&secret=e7a9b051283f7164ffc5a8dc2a7307db&code=" + code + "&grant_type=authorization_code";

        String jsonStr = HttpUtil.get(getUrl);//这是第二步
        Map<String, Object> ret = JSONUtil.toBean(jsonStr, HashMap.class);
         /*格式
       {
  "access_token":"ACCESS_TOKEN",
  "expires_in":7200,
  "refresh_token":"REFRESH_TOKEN",
  "openid":"OPENID",
  "scope":"SCOPE",
  "is_snapshotuser": 1,
  "unionid": "UNIONID"
        }
       * */
        String openId = ret.get("openid").toString();
        System.out.println("现在的openid是：：：：：：：：：：：：：：：：：：：：：：：：：：：" + openId);
        String weChattoken = ret.get("access_token").toString();
        if (weChattoken != null) {
            getUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + weChattoken + "&openid=" + openId + "&lang=zh_CN";
            jsonStr = HttpUtil.get(getUrl);//这是第四步，不需要第三部
          /*格式：{
            "openid": "OPENID",
                "nickname": NICKNAME,
                "sex": 1,
                "province":"PROVINCE",
                "city":"CITY",
                "country":"COUNTRY",
                "headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
                "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
            "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
        }*/
            ret = JSONUtil.toBean(jsonStr, HashMap.class);
            if (ret.get("openid") != null) {
                UserBaseInfo userBaseInfo = service.queryByOpenId(ret.get("openid").toString());
                UserDetailInfo detailInfo = new UserDetailInfo();
                //UserBaseInfo baseInfo =new UserBaseInfo();
                String token = null;
                if (userBaseInfo == null) {
                    UserBaseInfo baseInfo = new UserBaseInfo();
                    baseinfoService.save(baseInfo);
                    System.out.println("baseinfo是空的userid是：::::::::::::::::::::::::" + baseInfo.getId());
                    detailInfo.setNickname(ret.get("nickname").toString());
                    //custumer.setUserName(ret.get("nickname").toString());
                    //System.out.println(ret.get("sex") + ",=================");
                    detailInfo.setGender(ret.get("sex").toString());
                    //custumer.setSex(Integer.parseInt(ret.get("sex").toString()));
                    //custumer.setStatus(1);
                    //custumer.setAddress(StrUtil.concat(true, ret.get("country").toString(), ret.get("province").toString(), ret.get("city").toString()));
                    WeChatUser weChatUser = new WeChatUser();
                    weChatUser.setOpenId(ret.get("openid").toString());
                    service.newWeChatUser(baseInfo, detailInfo, weChatUser);
                    token = JwtUtil.genToken(baseInfo.getId());
                } else {
                    token = JwtUtil.genToken(userBaseInfo.getId());
                }
                //String tocken = service.createTocken(custmer);
                // 二维码页面需要一个 检查登录状态的定时访问，得到下面 redis的内容完成登录
                //Map<String, Object> map = new HashMap<>();
                //map.put("name", custmer.getName());
                //map.put("id", custmer.getId());
                //map.put("username", custmer.getUserName());
                //map.put("token", service.createTocken(custmer));
                System.out.println("token是:---------------------"+token);
                redisTemplate.opsForValue().set("token:"+state, token, 128, TimeUnit.HOURS);//二维码页面 延迟访问 做登录
                redisTemplate.opsForValue().set("token:"+token, token, 128, TimeUnit.HOURS);//二维码页面 延迟访问 做登录
                redisTemplate.opsForValue().set("weChatState:"+state, "200", 120, TimeUnit.SECONDS);//登陆成功
                //手机上看到的结果
                resp.getOutputStream().write("<html><body style='font-size:80px;color:red'>授权成功</body></html>".getBytes(StandardCharsets.UTF_8));
                return;
            }
        }
        redisTemplate.opsForValue().set(state, "300", 120, TimeUnit.SECONDS);//登陆失败
        resp.getOutputStream().write("<html><body>授权失败</body></html>".getBytes(StandardCharsets.UTF_8));

    }

    @GetMapping("/checkLogin")
    public Result checkLogin(String state) {
        System.out.println("state2:------------------------------"+state);
        System.out.println("state2.toString:------------"+state.toString());
        int i = 0;
        while (i <= 60) {//循环一分钟
            String redisKey = "weChatState:" + state;
            String loginStatus = redisTemplate.opsForValue().get(redisKey).toString();
            System.out.println("loginStatus:------------------------"+loginStatus);
            System.out.println("statuskey:" + redisKey);
            if ("200".equals(loginStatus)) {
//                JSONString redisValue = (JSONString) redisTemplate.opsForValue().get("weChatState:" + statekey);
//                Map<String, Object> ret = JSONUtil.toBean(redisValue, HashMap.class);
                String token = redisTemplate.opsForValue().get("token:"+state).toString();
                return Result.success(token);
            } else if ("300".equals(loginStatus)) {
                return Result.fail(400,"失败，请重试");
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            i++;
        }
        return Result.fail(null);
    }




}
